package com.hyjx.framework.component.log;

import com.hyjx.framework.common.Constants;
import com.hyjx.framework.common.util.StringHelper;
import com.hyjx.framework.component.codetable.CodeTableManager;
import com.hyjx.framework.service.ConfigManager;
import com.hyjx.framework.service.SessionManager;
import com.hyjx.framework.uc.user.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日志拦截器
 */
public class LogInterceptor implements HandlerInterceptor {
    Logger log = LoggerFactory.getLogger(LogInterceptor.class);
    public static final ThreadLocal<String> threadlocal = new ThreadLocal<String>();
    public static final ThreadLocal<String> odid = new ThreadLocal<String>();
    public static final ThreadLocal<String> sqloldrec = new ThreadLocal<String>();

    public LogInterceptor() {
    }

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
    }

    @SuppressWarnings("unchecked")
    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        
        String startTimeStr = threadlocal.get();
        long startTime = Long.parseLong(startTimeStr);

        if (req.getRequestURL().indexOf("logout") > -1) {
            UserInfo userModel = (UserInfo) SessionManager.get(Constants.USERINFO);
            req.setAttribute(Constants.USERINFO, userModel);
            return;
        }

        String bizlog = ConfigManager.getConfig("logIntereptor.bizlog");
        if (!"1".equals(bizlog)) {
            return;
        }
        String includePattern = ConfigManager.getConfig("logIntereptor.includePattern");
        if (includePattern == null || includePattern.trim().length() == 0) {
            return;
        }
        String url = req.getRequestURI().toLowerCase();
        if (url.indexOf("logbusiness") > -1) {
            return;
        }
        if (includePattern != null && includePattern.trim().length() > 0) {
            Pattern p = Pattern.compile(includePattern);
            Matcher m = p.matcher(url);
            if (!m.find()) {
                return;
            }
        }


        long endTime = System.currentTimeMillis();
        long executeTime = endTime - startTime;
        String ip = getIpAddr(req);
        String params = "";
        if (req.getParameterMap() != null) {
            String excludeField = ConfigManager.getConfig("logIntereptor.excludeField");
            if (StringUtils.isNotEmpty(excludeField)) {
                Pattern pattExcludeField = Pattern.compile(excludeField);
                for (Object key : req.getParameterMap().keySet()) {
                    if (!pattExcludeField.matcher(key.toString()).find())//if(key.toString().indexOf("pwd")==-1 && key.toString().indexOf("password")==-1)
                        params += key + "=" + ((Object[]) req.getParameterMap().get(key))[0] + ",";
                }
            }
        }
        UserInfo userInfo = new UserInfo();
        if (SessionManager.get(Constants.USERINFO) == null) {
            if (req.getAttribute(Constants.USERINFO) == null) {
                return;
            } else {
                userInfo = (UserInfo) req.getAttribute(Constants.USERINFO);
            }
        }
        if (SessionManager.get(Constants.USERINFO) != null) {
            try {
                userInfo = (UserInfo) SessionManager.get(Constants.USERINFO);
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
        }
        String moduleCode = "";
        String[] urlfrag = url.split("/");
        if (urlfrag.length > 2) {
            moduleCode = url.split("/")[2];
        }
        if (moduleCode.contains(".")) {
            moduleCode = moduleCode.split("\\.")[0];
        }
        String moduleName = CodeTableManager.getNameByCode("module", moduleCode);
        if (moduleName == null) {
            moduleName = "";
        }
        if (params != null && params.trim().length() > 0) {
            if (params.length() > 500) {
                params = params.substring(0, 500);
            }
            params = "参数：" + params;
        }
        

        LogBusinessModel model = new LogBusinessModel();
        model.setLog_id(StringHelper.getPrimaryKey());
        model.setIp_address(ip);
        model.setModule_name(moduleName);
        model.setModule_code(moduleCode);
        model.setExec_time(String.valueOf(executeTime));
        model.setOper_id(userInfo.getUser_account());
        model.setOper_name(userInfo.getUser_name());
        model.setOper_desc("访问地址：" + url + params);
        model.setOper_time(new Date());

        LogUtil.addLog(model);

        SessionManager.set("lbid", model.getLog_id());

    }

    /**
     * 获取客户端真实的IP地址
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0
                || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }


    /**
     * 拦截器 前处理事件
     *
     * @param req
     * @param rep
     * @param obj
     * @return
     *
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse rep, Object obj) throws Exception {
        long startTime = System.currentTimeMillis();
        threadlocal.set(startTime + "");
//		req.setAttribute("startTime", startTime);

        return true;
    }

}
